package com.hehe.conversion.hehemiddleware.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hehe.conversion.hehemiddleware.common.BusinessFieldMapper;
import com.hehe.conversion.hehemiddleware.common.IdcardFieldMapper;
import com.hehe.conversion.hehemiddleware.model.AppHead;
import com.hehe.conversion.hehemiddleware.model.RootBody;
import com.hehe.conversion.hehemiddleware.model.SysHead;
import com.hehe.conversion.hehemiddleware.model.req.BodyParam;
import com.hehe.conversion.hehemiddleware.model.req.ReqAppHead;
import com.hehe.conversion.hehemiddleware.model.resp.ocr.Item;
import com.hehe.conversion.hehemiddleware.model.resp.ocr.ResponseRoot;
import com.hehe.conversion.hehemiddleware.model.resp.ocr.bl.DetailItem;
import com.hehe.conversion.hehemiddleware.service.EsbRequestService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@Service
@Slf4j
public class EsbRequestServiceImpl implements EsbRequestService {

    @Value("${hehe.idcard.url}")
    private String idCardUrl;

    @Value("${hehe.business_license.url}")
    private String businessLicenseUrl;

    @Autowired
    RestTemplate restTemplate;

    @Value("${hehe.appkeyheader:App_key}")
    String appKeyHeaderName;

    @Value("${hehe.secretheader:App_secret}")
    String secretHeaderName;


    /**
     * 发送请求
     * @param url
     * @param request
     * @return
     */
    private JSONObject sendRequestAndParseResponse(String url, BodyParam request) {
        log.info("EsbRequestServiceImpl Sending request to: {}", url);
        HttpRequest httpRequest = HttpRequest.post(url)
                .contentType("application/json; charset=utf-8")
                .body(JSONObject.toJSONString(request));
        HttpResponse response = httpRequest.execute();
        log.info("EsbRequestServiceImpl Response status: {}, result: {}", response.getStatus(), response.body());
        if (response.isOk()) {
            return JSONObject.parseObject(response.body());
        } else {
            log.error(" EsbRequestServiceImpl Request to {} failed with status: {}", url, response.getStatus());
            throw new RuntimeException("Request to " + url + " failed with status: " + response.getStatus());
        }
    }

    /**
     * 失败的参数返回
     * @param msg
     * @return
     */
    private Map<String,String> failBody(String msg){
        Map<String,String> result=new HashMap<>();
        result.put("statYard","500");
        result.put("statInfo",msg);
        return result;
    }

    /**
     * 通用返回请求头数据
     * @param jsonObject
     * @param result
     */
    private void setAppAndSysHead(JSONObject jsonObject, RootBody result) {
        log.info("EsbRequestServiceImpl setAppAndSysHead");
        ReqAppHead appHead = jsonObject.getObject("appHead", ReqAppHead.class);
        SysHead sysHead = jsonObject.getObject("sysHead", SysHead.class);
        if (appHead != null) {
            result.setAppHead(AppHead.builder().appKey(appHead.getAppKey()).pswd(appHead.getAppSecret()).build());
        }
        if (sysHead != null) {
            result.setSysHead(sysHead);
        }
    }

    /**
     * 处理ocr返回数据
     * @param jsonObject
     * @param body
     * @param fieldMapper
     */
    private void handleResponseBody(JSONObject jsonObject, Map<String, String> body, Function<String, String> fieldMapper) {
        log.info("EsbRequestServiceImpl handleResponseBody");
        ResponseRoot responseRoot = jsonObject.getObject("body", ResponseRoot.class);
        body.put("statInfo", responseRoot.getMessage());
        body.put("statYard", responseRoot.getCode().toString());
        if (responseRoot.getDuration() != null) {
            body.put("rspnTm", responseRoot.getDuration().toString());
        }
        if (responseRoot != null && responseRoot.getCode() == 200) {
            JSONObject reqContent = JSONObject.parseObject(responseRoot.getReqContent());
            if(reqContent.containsKey("imgAddr")){
                body.put("imgAddr",reqContent.getString("imgAddr"));
            }
            if(reqContent.containsKey("imgBase64")){
                body.put("imgBase64",reqContent.getString("imgBase64"));
            }
            JSONObject jsonResult = JSONObject.parseObject(responseRoot.getResult());
            jsonResult.forEach((k,v)->{
                String fieldName = fieldMapper.apply(k);
                if(StringUtils.isNotBlank(fieldName)){
                    body.put(fieldName,v.toString());
                }
            });
            //处理身份证业务
            if(jsonResult.containsKey("item_list")){
                List<Item> itemList = JSONObject.parseArray(jsonResult.getString("item_list"), Item.class);
                if(CollectionUtil.isNotEmpty(itemList)){
                    itemList.forEach(item->{
                        String fieldName = fieldMapper.apply(item.getKey());
                        if(StringUtils.isNotBlank(fieldName)){
                            body.put(fieldName,item.getValue());
                        }
                    });
                }
            }
            //处理营业执照情况
            if(jsonResult.containsKey("details")){
                TypeReference<Map<String, DetailItem>> typeReference = new TypeReference<>() {};
                Map<String, DetailItem> details = JSON.parseObject(jsonResult.getString("details"), typeReference);
                if(CollectionUtil.isNotEmpty(details)){
                    details.forEach((k,v)->{
                        String fieldName = fieldMapper.apply(k);
                        if(StringUtils.isNotBlank(fieldName)){
                            body.put(fieldName,v.getValue());
                        }
                    });
                }
            }
        }
    }
    @Override
    public RootBody handleIdCardRequest(BodyParam request) {
        log.info("EsbRequestServiceImpl handleIdCardRequest");
        RootBody result = new RootBody();
        try {
            //JSONObject jsonObject = JSONObject.parseObject(FileUtil.readString("D:\\idcard.txt", "UTF-8"));
            JSONObject jsonObject = sendRequestAndParseResponse(idCardUrl, request);
            setAppAndSysHead(jsonObject, result);
            Map<String, String> body = new HashMap<>();
            handleResponseBody(jsonObject, body, IdcardFieldMapper::mapField);
            result.setBody(body);
            log.info("EsbRequestServiceImpl handleIdCardRequest success");
        } catch (Exception e) {
            log.error("EsbRequestServiceImpl handleIdCardRequest error", e);
            BeanUtils.copyProperties(request,result);
            result.setBody(failBody(e.getMessage()));
        }
        return result;
    }

    @Override
    public RootBody handleBusinessLicenseRequest(BodyParam request) {
        log.info("EsbRequestServiceImpl handleBusinessLicenseRequest");
        RootBody result = new RootBody();
        try {
            //JSONObject jsonObject = JSONObject.parseObject(FileUtil.readString("D:\\bussins.txt", "UTF-8"));
            JSONObject jsonObject = sendRequestAndParseResponse(businessLicenseUrl, request);
            setAppAndSysHead(jsonObject, result);
            Map<String, String> body = new HashMap<>();
            handleResponseBody(jsonObject, body, BusinessFieldMapper::mapField);
            result.setBody(body);
            log.info("EsbRequestServiceImpl handleIdCardRequest success");
        } catch (Exception e) {
            log.error("EsbRequestServiceImpl handleIdCardRequest error", e);
            BeanUtils.copyProperties(request,result);
            result.setBody(failBody(e.getMessage()));
        }
        return result;
    }


}
